//
//  max.h
//  HelloWorld
//
//  Created by Kevin Tang on 10/12/14.
//  Copyright (c) 2014年 Kevin Tang. All rights reserved.
//

#ifndef HelloWorld_max_h
#define HelloWorld_max_h

namespace TEMP {

    /*********************************************************************
     *模板函数，是由编译器在编译时，发现了符合模板的调用时，会产生一段函数实体。
     *
     *********************************************************************/
    template <typename T>//  其中 typename T 叫做模板参数,将类型做为参数传递
    
    inline T const& max(T const& a ,T const& b )//这里面的叫调用参数
    {
        return (a>b)?(a):(b);
    }
    
}

namespace TEMPA {
    //这里传递了两个不同类型的模板参数,似乎解决了比较 int,double 这样的问题。
    //但是这个会产生几个问题:在比较时，会发生类型转换，由于int,double是不同类型，所会发生类型转换
    //当发生类型转换时，会生成一会拷贝,降低了效率.
    //另外由于产生了类型转换，生成临时拷贝，所以就不能传回&，引用类型，因为临时拷贝在函数返回时不存在了.
    
    //关于引用的说明:
    //1:引用创建时，他必须初始化。即引用始终指向确定的地址，不能为空(而指针可以为空，可以作何时候初始化)
    //2:一旦一个引用被初始化指向某个对象,那么它就不可被修改为另一个对象的引用
    //3:不能有一个NULL引用，它必须与一块合法的存储单元相关链
    
    //另外由于两个类型不一样，所以我们要声明是返回T1,还是T2 类型。返回的值，与传入的值，不一样。
    //比如当传入:max(22,55.3) 时，由于55.3比22大，所以返回的是55.3但时，由于返回的是T1,而根据传入的参数，推导出来T1是int
    //导致了55.3发生类型转换为int丢失了小数部分。这并没有得到我们想要的结果。
    //其他两个不同类型的比较类似
    
    template <typename T1,typename T2 >
    inline T1 const max(T1 const& a ,T2 const& b )
    {
        return (a>b)?(a):(b);
    }
}


//另一种不同类型参数的解决方案
//在下面的方法中，我们明确指出了返回类型 RT
namespace TEMPC {
    template <typename T1 ,typename T2 ,typename RT>
     inline RT const max (T1 const&a ,T2 const&b)
    {
        return (a>b)?(a):(b);
    }

}
//将返回类型放在首位,即使这样，当发生类型转换时，还是不能返回引用
namespace TEMPD {
    template <typename RT,typename T1 ,typename T2 >
    inline RT const max (T1 const&a ,T2 const&b)
    {
        return (a>b)?(a):(b);
    }
    
}

//===========================下面这一部分讲模板函数重载======================
namespace TEMPE {
    
    //函数重载：是指函数名字相同，但函数的特征标不同，特征标即：函数的参数类型，个数，及参数的顺序。
    //带参函数列表，必须从右到左提供默认值，而实参则是从右到左，传递给参数的。中间不能间隔
    //默认参数的好处是:通过默认参数，可以减少定义的构造函数,方法，以及重载函数的数量。
    //但不好的地方就是，有时看代码时，看到某函数只传了一个实参，实际上是默认给了多个。
    
    
    //内联函数(接受两个int类型函数)
    inline int const& max(int const& a, int const& b)
    {
        return a>b?a:b;
    }
    //模板函数(接受两个任意类型的函数)
    template <typename T>
    inline T const& max(T const& a,T const&b)
    {
        return a>b?a:b;
    }
    //模板函数(接受两个任意类型的函数)
    template <typename T>
    inline T const& max(T const& a,T const&b,T const&c)
    {
        return TEMPE::max(TEMPE::max(a, b),c);
    }
    
    
    
}



#endif
